#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
#include <thread>

// 线程的局部存储
// __thread只能修饰内置类型
__thread int shared_value = 100;

std::string toHex(pthread_t tid)
{
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "0x%lx", tid);
    return buffer;
}

void *start(void *args)
{
    std::string name = static_cast<const char *>(args);
    sleep(1);
    while (true)
    {
        printf("I am a new thread, name: %s, shared_value: %d,  &shared_value: %p\n", name.c_str(), shared_value, &shared_value);
        sleep(1);
    }

    return nullptr;
}

int main()
{
    pthread_attr_t attr;

    
    pthread_t tid;
    pthread_create(&tid, nullptr, start, (void *)"thread-1");
    std::cout << "I am a new thread, name: main, " << toHex(pthread_self())
              << ", NEW thread id: " << toHex(tid) << std::endl;

    while (true)
    {
        printf("main thread, shared_value: %d,  &shared_value: %p\n", shared_value, &shared_value);
        shared_value += 10;
        sleep(1);
    }
    pthread_join(tid, nullptr);
    return 0;
}


// void *start(void *args)
// {
//     pthread_detach(pthread_self());
//     std::string name = static_cast<const char *>(args);
//     while(true)
//     {
//         std::cout<<"I am a new thread"<<std::endl;
//         sleep(1);
//         //break;
//     }
//     //9.新线程return，表示该进程退出
//     //return 0;
//     //任何地方调用exit，表示进程退出
//     //exit(1); 

//     //pthread_exit((void*)10);

// }

// int main()
// {
//     pthread_t tid;

//     pthread_create(&tid,nullptr,start,(void*)"thread-1");
//     pthread_detach(tid);
//     sleep(5);

//     // pthread_cancel(tid);
//     // std::cout<<"取消线程："<<tid<<std::endl;

//     // sleep(5);

//     void*ret = nullptr;
//     int n = pthread_join(tid,&ret);
//     std::cout<<"new thread exit code: "<<(long long)ret<<std::endl;
//     std::cout<<"n: "<<n<<std::endl;
//     return 0;//9. 主线程return，表示进程结束
// }







// int *addr = nullptr;

// void *start1(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     int a = 100;
//     addr = &a;
//     while(true)
//     {
//         std::cout<<name<<" local val a: "<<a<<std::endl;
//         sleep(1);
//     }
// }

// void *start2(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     while(true)
//     {
//         if(addr != nullptr)
//         std::cout<<name<<" mod val a: "<<(*addr)++<<std::endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     pthread_t tid1,tid2;

//     pthread_create(&tid1,nullptr,start1,(void*)"thread-1");
//     pthread_create(&tid2,nullptr,start2,(void*)"thread-2");

//     pthread_join(tid1,nullptr);
//     pthread_join(tid2,nullptr);
//     return 0;
// }





// class ThreadData
// {
// public:
//     ThreadData()
//     {}
//     void Init(const std::string &name, int a, int b)
//     {
//         _name = name;
//         _a = a;
//         _b = b;
//     }
//     void Excute()
//     {
//         _result = _a + _b;
//     }
//     int A(){return _a;}
//     int B(){return _b;}
//     std::string Name() { return _name; }
//     int Result(){return _result;}
//     void SetId(pthread_t tid){_tid = tid;}
//     pthread_t Id(){return _tid;}
//     ~ThreadData()
//     {}

// private:
//     std::string _name;
//     int _a;
//     int _b;
//     int _result;
//     pthread_t _tid;
// };

// int gval = 100;

// std::string toHex(pthread_t tid)
// {
//     // 4.进程内的函数，线程共享
//     char buffer[64];
//     snprintf(buffer, sizeof(buffer), "0x%lx", tid);
//     return buffer;
// }

// void *routine(void *args)
// {
//     // std::string name = static_cast<const char *>(args);
//     ThreadData *td = static_cast<ThreadData *>(args);

//     while (true)
//     {
//         std::cout << "我是新线程，我的名字是：" << td->Name() << ", my tid is : " << toHex(pthread_self()) << ",全局变量（会修改）：" << gval << std::endl;
//         gval++;
//         //新线程完成任务，主线程打印结果
//         td->Excute();
//         sleep(1);
//         break;
//     }
//     // 8.返回值问题:返回参数：可以是变量，数字，对象
//     // 8.1 :理论上，堆空间也是共享的，谁拿着堆空间的入口地址，谁就可以访问该堆区
//     //return (void *)10; // 线程退出方式1：线程入口函数return，表示线程退出
//     // int *p = new int(10);
//     // return (void*)p;
//     return td;
// }

// #define NUM 10

// int main()
// {
//     ThreadData td[NUM];
//     //准备我们要加工处理的数据
//     for(int i = 0;i<NUM;i++)
//     {
//         char id[64];
//         snprintf(id,sizeof(id),"thread-%d",i);
//         td[i].Init(id,i*10,i*20);
//     }

//     //创建多线程
//     for(int i=0;i<NUM;i++)
//     {
//         pthread_t id;
//         pthread_create(&id,nullptr,routine,&td[i]);
//         td[i].SetId(id);
//     }

//     //等待多个线程
//     for(int i=0;i<NUM;i++)
//     {
//         pthread_join(td[i].Id(),nullptr);
//     }

//     //汇总处理结果
//     for(int i = 0;i<NUM;i++)
//     {
//         printf("td[%d] : %d+%d=%d[%ld]\n",i,td[i].A(),td[i].B(),td[i].Result(),td[i].Id());
//     }
//     return 0;
// }


// int main()
// {
//     pthread_t tid1;
//     // 8.传参问题
//     // （void）--》可以传任意类型参数,变量，结构体，对象
//     ThreadData *td = new ThreadData("thread-1", 10, 20);
//     // pthread_create(&tid1, nullptr, routine1, (void *)"thread-1");
//     pthread_create(&tid1, nullptr, routine1, td);

//     // 7.线程创建之后，也是要被等待和回收的
//     // 7.1 理由：a.类似僵尸进程的问题 b. 为了知道新线程的执行结果
//    ThreadData *ret = nullptr;
//     int n = pthread_join(tid1, (void**)&ret); //我们可以保证，执行完毕，任务一定处理问了，结果变量一定被写入了，结果可信
//     if (n != 0)
//     {
//         std::cout << "等待失败:" << n << "," << strerror(n) << std::endl;
//         return 1;
//     }
//     //新线程完成任务，主线程打印结果
//     std::cout << "等待成功,ret:" << ret->Result() << std::endl;
//     delete td;
//     return 0;
// }





// // 5.全局变量在线程内部都是共享的
// int gval = 100;

// std::string toHex(pthread_t tid)
// {
//     // 4.进程内的函数，线程共享
//     char buffer[64];
//     snprintf(buffer, sizeof(buffer), "0x%lx", tid);
//     return buffer;
// }

// // routine函数被重入了
// void *routine1(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     while (true)
//     {
//         // 不加保护的情况下，显示器文件就是共享资源
//         std::cout << "我是新线程，我的名字是：" << name << ", my tid is : " << toHex(pthread_self()) << ",全局变量（会修改）：" << gval << std::endl;
//         gval++;
//         sleep(1);
//     }
//     return 0;
// }

// void *routine2(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     while (true)
//     {
//         // 不加保护的情况下，显示器文件就是共享资源
//         std::cout << "我是新线程，我的名字是：" << name << ", my tid is : " << toHex(pthread_self()) << ",全局变量（只检查）：" << gval << std::endl;
//         sleep(1);
//         // 6.线程一旦出现异常，可能会导致其他的线程全部崩溃
//         //6.1 触发软中断，向进程发送信号
//         // int *p = nullptr;
//         // *p = 100;
//     }
//     return 0;
// }

// int main()
// {
//     // 1.新线程和主线程谁先运行，不确定
//     // 2.线程创建出来，要对进程的时间片进行瓜分
//     pthread_t tid1;
//     pthread_create(&tid1, nullptr, routine1, (void *)"thread-1");
//     pthread_t tid2;
//     pthread_create(&tid2, nullptr, routine2, (void *)"thread-1");
//     // pthread_t tid3;
//     // pthread_create(&tid3, nullptr, routine, (void *)"thread-1");
//     // pthread_t tid4;
//     // pthread_create(&tid4, nullptr, routine, (void *)"thread-1");

//     printf("new thread id : 0x%lx\n", tid1);
//     printf("new thread id : 0x%lx\n", tid2);
//     // printf("new thread id : 0x%lx\n", tid3);
//     // printf("new thread id : 0x%lx\n", tid4);

//     while (true)
//     {
//         std::cout << "我是main进程..." << std::endl;
//         sleep(1);
//     }
//     return 0;
// }





// void *routine(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     while (true)
//     {
//         std::cout << "我是新线程，我的名字是：" << name << std::endl;
//         sleep(1);
//     }
//     return 0;
// }

// int main()
// {
//     std::thread t([](){
//         while(true)
//         {
//         std::cout << "我是新线程，我的名字是：new thread" << std::endl;
//         sleep(1);
//         }
//     });
//     while(true)
//     {
//         std::cout<<"我是main进程..."<<std::endl;
//         sleep(1);
//     }
// }

// void *routine(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     while (true)
//     {
//         std::cout << "我是新线程，我的名字是：" << name << std::endl;
//         sleep(1);
//     }
//     return 0;
// }

// int main()
// {
//     pthread_t tid;
//     int n = pthread_create(&tid, nullptr, routine, (void *)"thread -1");
//     if (n != 0)
//     {
//         std::cout << "create thread error: " << strerror(n) << std::endl;
//         return 1;
//     }
//     while(true)
//     {
//         std::cout<<"我是main进程..."<<std::endl;
//         sleep(1);
//     }
// }






// // 新线程
// void *run(void *args)
// {
//     while(true)
//     {
//         std::cout << "new thread, pid: " << getpid() << std::endl;
//         sleep(1);
//     }
//     return nullptr;
// }

// int main()
// {
//     std::cout << "我是一个进程: " << getpid() << std::endl;
//     pthread_t tid;
//     pthread_create(&tid, nullptr, run, (void*)"thread-1");

//     // 主线程
//     while(true)
//     {
//         std::cout << "main thread, pid: "<< getpid() << std::endl;
//         sleep(1);
//     }

//     return 0;
// }